* Nick Petrovsky
* nicolai.petrovsky@uky.edu

* This do-file generates the tables and analyses reported in 
* Petrovsky/Mok/Leon-Cazares (2016, Public Administration Review): 
* "Citizen Expectations and Satisfaction in a Young Democracy: 
* A Test of the Expectancy-Disconfirmation Model"

* Stata version 14.1
* last modified September 27, 2016

* Do-file requires the cibar, mkcorr, and outreg2 
* ados to be installed

* See http://www.ats.ucla.edu/stat/stata/faq/catcon12.htm 
* about the interaction graphs

* Data set required: 
* PetrovskyMokLeon2016PAR.dta

* Please copy this do-file and the data sets into a
* directory on your hard drive.
* Then, please use Stata's command
* cd
* to change to that directory.
* Now you can run this do-file.

clear
clear matrix
version 14.1
set more off
set scheme s1mono

* Open a log and allow for replacement
log using PetrovskyMokLeon2016PAR, replace

* Open the data
use PetrovskyMokLeon2016PAR.dta
save workfile, replace

* Balance tests for whole sample (2104)
ttest Q02_visit, by(Q00_normative_exp_Q)
* Get raw numbers of respondents
tab Q02_visit Q00_normative_exp_Q
ttest Q11_female, by(Q00_normative_exp_Q)
ttest Q12_age, by(Q00_normative_exp_Q)
ttest Q13_education, by(Q00_normative_exp_Q)
ttest Q14_formal_job, by(Q00_normative_exp_Q)
ttest Q15_informal_job, by(Q00_normative_exp_Q)
ttest Q16_party_or_candidate, by(Q00_normative_exp_Q)
ttest _PAN, by(Q00_normative_exp_Q)
ttest _PRI, by(Q00_normative_exp_Q)
ttest _PRD, by(Q00_normative_exp_Q)
ttest _MovCiud, by(Q00_normative_exp_Q)
ttest _other_party, by(Q00_normative_exp_Q)
ttest _no_fav_party, by(Q00_normative_exp_Q)
ttest Would_like_results, by(Q00_normative_exp_Q)

* Balance tests for those in the study (1302)
ttest Q11_female if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q12_age if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q13_education if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q14_formal_job if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q15_informal_job if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q16_party_or_candidate if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _PAN if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _PRI if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _PRD if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _MovCiud if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _other_party if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _no_fav_party if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Would_like_results if Q02_visit == 1, by(Q00_normative_exp_Q)

* Balance tests for those in the study, by location (to check interviewer team effects)
bysort Team_location: ttest Q08_satisfaction_overall if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q06_satisfaction_time if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q07_satisfaction_employee if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q13_education if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q11_female if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest _PAN if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest _PRI if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest _PRD if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest _MovCiud if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest _other_party if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q03_experience if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q04_waittime if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q05_employee if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q12_age if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q14_formal_job if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q15_informal_job if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Q16_party_or_candidate if Q02_visit == 1, by(Q00_normative_exp_Q)
bysort Team_location: ttest Would_like_results if Q02_visit == 1, by(Q00_normative_exp_Q)

* Check differences in expectations
ttest _Z_expec if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q01_expectation_level if Q02_visit == 1, by(Q00_normative_exp_Q)

* Check differences in perceived performance
ttest _Z_perfO if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q03_experience if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _Z_perfT if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q04_waittime if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest _Z_perfE if Q02_visit == 1, by(Q00_normative_exp_Q)
ttest Q05_employee if Q02_visit == 1, by(Q00_normative_exp_Q)

* Define the estimation sample for the models: 

quietly reg _Z_satO i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if Q02_visit == 1
gen e_sample2O = 1 if e(sample)

quietly reg _Z_satT i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if Q02_visit == 1
gen e_sample2T = 1 if e(sample)

quietly reg _Z_satE i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if Q02_visit == 1
gen e_sample2E = 1 if e(sample)

gen common_e_sample2 = 1 if e_sample2O == 1 & e_sample2T == 1 & e_sample2E == 1

lab var _sat_dummy_O "Satisfied overall (dummy)"
lab var _sat_dummy_T "Satisfied with wait time (dummy)"
lab var _sat_dummy_E "Satisfied with employee (dummy)"
lab var _dissat_dummy_O "Dissatisfied overall (dummy)"
lab var _dissat_dummy_T "Dissatisfied with wait time (dummy)"
lab var _dissat_dummy_E "Dissatisfied with employee (dummy)"
lab def Q00_normative_exp_Q 0 Empirical 1 Normative
lab val Q00_normative_exp_Q Q00_normative_exp_Q
compress
save, replace

* Simple comparisons

* Table 1: Balance tests for those in the estimation sample (1144)
ttest _sat_dummy_O if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _sat_dummy_T if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _sat_dummy_E if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _dissat_dummy_O if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _dissat_dummy_T if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _dissat_dummy_E if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_expec if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_discO if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_discT if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_discE if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _HSgrad if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _UniGrad if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q11_female if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _PAN if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _PRI if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _PRD if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _MovCiud if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _other_party if common_e_sample2 == 1, by(Q00_normative_exp_Q)
* Balance tests for other respondent characteristics: 
ttest Q01_expectation_level if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q03_experience if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q04_waittime if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q05_employee if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q12_age if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q14_formal_job if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q15_informal_job if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Q16_party_or_candidate if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest Would_like_results if common_e_sample2 == 1, by(Q00_normative_exp_Q)

* Figure 1 (for the model estimation sample)
* Do % satisfied and % dissatisfied differ between the two groups?  

ttest _sat_dummy_O if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _sat_dummy_O if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1a_1.png, replace

ttest _sat_dummy_T if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _sat_dummy_T if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1a_2.png, replace

ttest _sat_dummy_E if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _sat_dummy_E if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1a_3.png, replace

ttest _dissat_dummy_O if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _dissat_dummy_O if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1b_1.png, replace

ttest _dissat_dummy_T if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _dissat_dummy_T if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1b_2.png, replace

ttest _dissat_dummy_E if common_e_sample2 == 1, by(Q00_normative_exp_Q)
cibar _dissat_dummy_E if common_e_sample2 == 1, level(95) over1(Q00_normative_exp_Q) /*
*/ graphopts(title("") yscale(r(.15 .50)) ylabel(.2(.1).5) legend(off))
graph export edm_Figure1b_3.png, replace

* 2) Does the unconditional mean of expectations differ between the 
* two groups?  
ttest _Z_expec if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_expec, by(Q00_normative_exp_Q)

* 3) Does the unconditional mean of perceptions of performance differ 
* between the two groups?  
ttest _Z_perfO if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_perfT if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_perfE if common_e_sample2 == 1, by(Q00_normative_exp_Q)
ttest _Z_perfO, by(Q00_normative_exp_Q)
ttest _Z_perfT, by(Q00_normative_exp_Q)
ttest _Z_perfE, by(Q00_normative_exp_Q)

* Expectancy-disconfirmation models for satisfaction overall, with the time 
* it took, and with the employee's competence

* Appendix B: Correlation matrix

* Generating variables with short names to make 
* the correlation matrix fit on one page
gen _1 = _sat_dummy_O
gen _2 = _sat_dummy_T
gen _3 = _sat_dummy_E
gen _4 = _dissat_dummy_O
gen _5 = _dissat_dummy_T
gen _6 = _dissat_dummy_E
gen _7 = Q00_normative_exp_Q
gen _8 = _Z_expec
gen _9 = _Z_discO
gen _10 = _Z_discT
gen _11 = _Z_discE
gen _12 = _HSgrad
gen _13 = _UniGrad
gen _14 = Q11_female
gen _15 = _PAN
gen _16 = _PRI
gen _17 = _PRD
gen _18 = _MovCiud
gen _19 = _other_party

mkcorr _1-_19 /*
*/ if common_e_sample2 == 1, log(AppendixCCorrMatrix.txt) /*
*/ replace casewise sig num cdec(2)

* Check: What Tables 2 & 3 would be for a 
* continuous dependent variable "degrees of citizen satisfaction"

* (i) Overall satisfaction
reg _Z_satO i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using TableX1.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall) word replace

* Check: same model without controls
reg _Z_satO i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using TableX2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall) word replace

* (ii) Satisfaction with the time it took
reg _Z_satT i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using TableX1.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time) word append

* Check: same model without controls
reg _Z_satT i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using TableX2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time) word append

* (iii) Satisfaction with employee
reg _Z_satE i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using TableX1.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee) word append

* Check: same model without controls
reg _Z_satE i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using TableX2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee) word append

* Table 2: Binary probit of satisfaction

* 2.1 Overall satisfaction
probit _sat_dummy_O i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall_a) word replace

* Figure (not in text): Any conditional treatment effect?
sum _Z_discO if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discO=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model2_1disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discO = (-2 2))

* Check: same model without controls
probit _sat_dummy_O i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall_b) word append

* 2.2 Satisfaction with the time it took
probit _sat_dummy_T i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time_a) word append

* Figure (not in text): Any conditional treatment effect?
sum _Z_discT if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discT=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model2_2disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discT = (-2 2))

* Check: same model without controls
probit _sat_dummy_T i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time_b) word append

* 2.3 Satisfaction with employee
probit _sat_dummy_E i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee_a) word append

* Figure (not in text): Any conditional treatment effect?
sum _Z_discE if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discE=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model2_3disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discE = (-2 2))

* Check: same model without controls
probit _sat_dummy_E i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table2.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee_b) word append

* Table 3: Binary probit of dissatisfaction

* 3.1 Overall dissatisfaction
probit _dissat_dummy_O i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall_a) word replace

* Figure (not in text): Any conditional treatment effect?
sum _Z_discO if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discO=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model3_1disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discO = (-2 2))

* Check: same model without controls
probit _dissat_dummy_O i.Q00_normative_exp_Q##c._Z_discO /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Overall_b) word append

* 3.2 Dissatisfaction with the time it took
probit _dissat_dummy_T i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time_a) word append

* Figure (not in text): Any conditional treatment effect?
sum _Z_discT if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discT=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model3_2disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discT = (-2 2))

* Check: same model without controls
probit _dissat_dummy_T i.Q00_normative_exp_Q##c._Z_discT /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Time_b) word append

* 3.3 Dissatisfaction with employee
probit _dissat_dummy_E i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ _HSgrad _UniGrad Q11_female _PAN _PRI _PRD _MovCiud _other_party if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee_a) word append

* Figure (not in text): Any conditional treatment effect?
sum _Z_discE if e(sample), d
margins, dydx(Q00_normative_exp_Q) atmeans at(_Z_discE=(-2(.5)2)) vsquish
marginsplot, level(95) recast(line) recastci(rarea) yline(0) title("") legend(off)
graph export Model3_3disconfirmation.png, replace

* For article text: substantive interpretation of 
* "performance minus expectation"
margins, atmeans at(_Z_discE = (-2 2))

* Check: same model without controls
probit _dissat_dummy_E i.Q00_normative_exp_Q##c._Z_discE /*
*/ i.Q00_normative_exp_Q##c._Z_expec /*
*/ if common_e_sample2 == 1
outreg2 using Table3.doc, tstat bdec(2) tdec(2) /*
*/ ctitle(Employee_b) word append

save, replace
clear
log close
exit
